<template>
  <Teleport to="body">
    <Transition name="modal-fade">
      <div v-if="modelValue" class="modal-overlay" @click="handleOverlayClick">
        <div class="modal-container" :style="modalStyle" @mousedown="startDrag" @mousemove="onDrag" @mouseup="stopDrag"
          @mouseleave="stopDrag">
          <!-- 标题栏 -->
          <div class="modal-header">
            <slot name="header">
              <h3>{{ title }}</h3>
            </slot>
            <button class="modal-close" @click="close">×</button>
          </div>

          <!-- 内容区 -->
          <div class="modal-body">
            <slot>
              {{ content }}
            </slot>
          </div>

          <!-- 按钮区 -->
          <div class="modal-footer">
            <slot name="footer">
              <button class="modal-btn cancel" v-if="showCancel" @click="cancel">取消</button>
              <button class="modal-btn confirm" @click="confirm">确定</button>
            </slot>
          </div>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue';

const props = defineProps({
  modelValue: Boolean, // v-model绑定值
  title: {
    type: String,
    default: '提示'
  },
  content: String,
  width: {
    type: [String, Number],
    default: '500px'
  },
  height: {
    type: [String, Number],
    default: 'auto'
  },
  showCancel: {
    type: Boolean,
    default: true
  },
  closeOnClickOverlay: {
    type: Boolean,
    default: true
  },
  draggable: {
    type: Boolean,
    default: true
  }
});

const emit = defineEmits(['update:modelValue', 'confirm', 'cancel']);

// 处理拖拽逻辑
const isDragging = ref(false);
const dragOffset = ref({ x: 0, y: 0 });
const position = ref({ x: 0, y: 0 });

const modalStyle = computed(() => {
  return {
    width: typeof props.width === 'number' ? `${props.width}px` : props.width,
    height: typeof props.height === 'number' ? `${props.height}px` : props.height,
    transform: `translate(${position.value.x}px, ${position.value.y}px)`
  };
});

function startDrag(event: MouseEvent) {
  if (!props.draggable) return;
  if (
    event.target &&
    (event.target as HTMLElement).closest &&
    (event.target as HTMLElement).closest('.modal-header')
  ) {
    isDragging.value = true;
    dragOffset.value = {
      x: event.clientX - position.value.x,
      y: event.clientY - position.value.y
    };
  }
}

function onDrag(event: MouseEvent) {
  if (isDragging.value) {
    position.value = {
      x: event.clientX - dragOffset.value.x,
      y: event.clientY - dragOffset.value.y
    };
  }
}

function stopDrag() {
  isDragging.value = false;
}

function close() {
  emit('update:modelValue', false);
}

function confirm() {
  emit('confirm');
  close();
}

function cancel() {
  emit('cancel');
  close();
}

function handleOverlayClick(event: MouseEvent) {
  // 只有点击遮罩层而不是弹窗本身才关闭
  if (
    props.closeOnClickOverlay &&
    event.target &&
    (event.target as HTMLElement).classList.contains('modal-overlay')
  ) {
    close();
  }
}

// 按ESC键关闭弹窗
function handleKeyDown(event: KeyboardEvent) {
  if (event.key === 'Escape' && props.modelValue) {
    close();
  }
}

onMounted(() => {
  window.addEventListener('keydown', handleKeyDown);
});

onUnmounted(() => {
  window.removeEventListener('keydown', handleKeyDown);
});
</script>

<style scoped>
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal-container {
  background-color: #ffffff;
  border-radius: 4px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  max-width: 90%;
  max-height: 90%;
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #e8e8e8;
  cursor: move;
}

.modal-body {
  padding: 16px;
  overflow-y: auto;
  flex: 1;
}

.modal-footer {
  padding: 12px 16px;
  border-top: 1px solid #e8e8e8;
  text-align: right;
}

.modal-close {
  border: none;
  background: transparent;
  font-size: 20px;
  cursor: pointer;
  outline: none;
}

.modal-btn {
  padding: 8px 15px;
  margin-left: 10px;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  background: #fff;
  cursor: pointer;
}

.modal-btn.confirm {
  background-color: #409eff;
  color: #fff;
  border-color: #409eff;
}

/* 过渡动画 */
.modal-fade-enter-active,
.modal-fade-leave-active {
  transition: opacity 0.3s;
}

.modal-fade-enter-from,
.modal-fade-leave-to {
  opacity: 0;
}
</style>
